using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Lzfy_Refund_Service.Services;
using System.Diagnostics;

namespace Lzfy_Refund_Service.Controllers
{
    /// <summary>
    /// 健康检查控制器
    /// </summary>
    [ApiController]
    [Route("api/[controller]")]
    public class HealthController : ControllerBase
    {
        private readonly ILogger<HealthController> _logger;
        private readonly ApplicationHealthCheckService _healthCheckService;
        private readonly PasswordUpdateBackgroundService _passwordService;
        private readonly DatabaseHealthCheckService _databaseHealthService;

        public HealthController(
            ILogger<HealthController> logger,
            ApplicationHealthCheckService healthCheckService,
            PasswordUpdateBackgroundService passwordService,
            DatabaseHealthCheckService databaseHealthService)
        {
            _logger = logger;
            _healthCheckService = healthCheckService;
            _passwordService = passwordService;
            _databaseHealthService = databaseHealthService;
        }

        /// <summary>
        /// 基础健康检查端点
        /// </summary>
        [HttpGet]
        [AllowAnonymous]
        public IActionResult Get()
        {
            try
            {
                var (isHealthy, lastCheckTime, metrics) = _healthCheckService.GetHealthStatus();
                
                if (isHealthy)
                {
                    return Ok(new
                    {
                        status = "healthy",
                        timestamp = DateTime.Now,
                        lastCheckTime = lastCheckTime,
                        uptime = GetUptime()
                    });
                }
                else
                {
                    return StatusCode(503, new
                    {
                        status = "unhealthy",
                        timestamp = DateTime.Now,
                        lastCheckTime = lastCheckTime,
                        uptime = GetUptime()
                    });
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "健康检查失败");
                return StatusCode(503, new
                {
                    status = "error",
                    message = "健康检查服务异常",
                    timestamp = DateTime.Now
                });
            }
        }

        /// <summary>
        /// 详细健康检查端点
        /// </summary>
        [HttpGet("detailed")]
        [Authorize(Roles = "Admin,SystemAdmin")]
        public IActionResult GetDetailed()
        {
            try
            {
                var (isHealthy, lastCheckTime, metrics) = _healthCheckService.GetHealthStatus();
                var (passwordServiceHealthy, consecutiveErrors, lastSuccessTime) = _passwordService.GetHealthStatus();
                var (sqlHealthy, oracleHealthy, lastSqlCheck, lastOracleCheck) = _databaseHealthService.GetDatabasesHealth();

                var result = new
                {
                    overall = new
                    {
                        status = isHealthy ? "healthy" : "unhealthy",
                        timestamp = DateTime.Now,
                        uptime = GetUptime()
                    },
                    applicationHealth = new
                    {
                        isHealthy = isHealthy,
                        lastCheckTime = lastCheckTime,
                        metrics = metrics
                    },
                    backgroundServices = new
                    {
                        passwordUpdateService = new
                        {
                            isHealthy = passwordServiceHealthy,
                            consecutiveErrors = consecutiveErrors,
                            lastSuccessTime = lastSuccessTime
                        },
                        databaseHealthService = new
                        {
                            sqlServer = new
                            {
                                isHealthy = sqlHealthy,
                                lastCheckTime = lastSqlCheck
                            },
                            oracle = new
                            {
                                isHealthy = oracleHealthy,
                                lastCheckTime = lastOracleCheck
                            }
                        }
                    },
                    system = new
                    {
                        processId = Environment.ProcessId,
                        machineName = Environment.MachineName,
                        osVersion = Environment.OSVersion.ToString(),
                        dotNetVersion = Environment.Version.ToString(),
                        workingSet = Environment.WorkingSet,
                        gcTotalMemory = GC.GetTotalMemory(false)
                    }
                };

                if (isHealthy && passwordServiceHealthy && sqlHealthy && oracleHealthy)
                {
                    return Ok(result);
                }
                else
                {
                    return StatusCode(503, result);
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "详细健康检查失败");
                return StatusCode(500, new
                {
                    status = "error",
                    message = "健康检查服务异常",
                    error = ex.Message,
                    timestamp = DateTime.Now
                });
            }
        }

        /// <summary>
        /// 就绪检查端点（用于容器编排）
        /// </summary>
        [HttpGet("ready")]
        [AllowAnonymous]
        public IActionResult Ready()
        {
            try
            {
                var (sqlHealthy, oracleHealthy, _, _) = _databaseHealthService.GetDatabasesHealth();
                
                if (sqlHealthy && oracleHealthy)
                {
                    return Ok(new
                    {
                        status = "ready",
                        timestamp = DateTime.Now
                    });
                }
                else
                {
                    return StatusCode(503, new
                    {
                        status = "not ready",
                        message = "数据库连接异常",
                        timestamp = DateTime.Now
                    });
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "就绪检查失败");
                return StatusCode(503, new
                {
                    status = "not ready",
                    message = "就绪检查异常",
                    timestamp = DateTime.Now
                });
            }
        }

        /// <summary>
        /// 存活检查端点（用于容器编排）
        /// </summary>
        [HttpGet("live")]
        [AllowAnonymous]
        public IActionResult Live()
        {
            try
            {
                // 简单的存活检查，只要进程还在运行就返回成功
                return Ok(new
                {
                    status = "alive",
                    timestamp = DateTime.Now,
                    processId = Environment.ProcessId
                });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "存活检查失败");
                return StatusCode(500, new
                {
                    status = "error",
                    message = "存活检查异常",
                    timestamp = DateTime.Now
                });
            }
        }

        /// <summary>
        /// 手动触发垃圾回收
        /// </summary>
        [HttpPost("gc")]
        [Authorize(Roles = "Admin,SystemAdmin")]
        public IActionResult TriggerGarbageCollection()
        {
            try
            {
                var beforeMemory = GC.GetTotalMemory(false);
                
                GC.Collect();
                GC.WaitForPendingFinalizers();
                GC.Collect();
                
                var afterMemory = GC.GetTotalMemory(false);
                var freedMemory = beforeMemory - afterMemory;
                
                _logger.LogInformation("手动触发垃圾回收，释放内存: {FreedMemory} bytes", freedMemory);
                
                return Ok(new
                {
                    message = "垃圾回收完成",
                    beforeMemory = beforeMemory,
                    afterMemory = afterMemory,
                    freedMemory = freedMemory,
                    timestamp = DateTime.Now
                });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "手动垃圾回收失败");
                return StatusCode(500, new
                {
                    message = "垃圾回收失败",
                    error = ex.Message,
                    timestamp = DateTime.Now
                });
            }
        }

        /// <summary>
        /// 获取应用运行时间
        /// </summary>
        private TimeSpan GetUptime()
        {
            using var process = Process.GetCurrentProcess();
            return DateTime.Now - process.StartTime;
        }
    }
}